package com.snakerflow.framework.ws.web;

import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.snaker.engine.entity.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.snakerflow.framework.flow.service.ApprovalManager;
import com.snakerflow.framework.flow.service.SnakerEngineFacets;
import com.snakerflow.framework.utils.ConvertUtils;
import com.snakerflow.framework.ws.Constant;
import com.snakerflow.framework.ws.vo.WsCommonResponse;

/**
 * Snaker流程引擎流程实例相关Controller
 * @author 何东
 * @since 2.0
 */
@Controller
@RequestMapping(value = "/ws/snaker/flow")
public class WsFlowController {
    
    @Autowired
    private SnakerEngineFacets facets;
    @Autowired
    private ApprovalManager manager;
    
    /**
     * 启动、审批、驳回、转办、协办
     * @param request
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
	@ResponseBody
	@RequestMapping(value = "process")
    public WsCommonResponse process(HttpServletRequest request) {
    	WsCommonResponse wsResp = new WsCommonResponse();
    	Map<String, Object> params = new HashMap<String, Object>();
        Enumeration<String> paraNames = request.getParameterNames();
        while (paraNames.hasMoreElements()) {
            String element = paraNames.nextElement();
            int index = element.indexOf("_");
            String paraValue = request.getParameter(element);
            if(index == -1) {
                params.put(element, paraValue);
            } else {
                char type = element.charAt(0);
                String name = element.substring(index + 1);
                Object value = null;
                switch(type) {
                    case 'S':
                        value = paraValue;
                        break;
                    case 'I':
                        value = ConvertUtils.convertStringToObject(paraValue, Integer.class);
                        break;
                    case 'L':
                        value = ConvertUtils.convertStringToObject(paraValue, Long.class);
                        break;
                    case 'B':
                        value = ConvertUtils.convertStringToObject(paraValue, Boolean.class);
                        break;
                    case 'D':
                        value = ConvertUtils.convertStringToObject(paraValue, Date.class);
                        break;
                    case 'N':
                        value = ConvertUtils.convertStringToObject(paraValue, Double.class);
                        break;
                    default:
                        value = paraValue;
                        break;
                }
                params.put(name, value);
            }
        }
        String processId = request.getParameter(Constant.PARA_PROCESSID);
        String orderId = request.getParameter(Constant.PARA_ORDERID);
        String taskId = request.getParameter(Constant.PARA_TASKID);
        String nextOperator = request.getParameter(Constant.PARA_NEXTOPERATOR);
        String operator = request.getParameter(Constant.PARA_OPERATOR);
        if (StringUtils.isEmpty(orderId) && StringUtils.isEmpty(taskId)) {
        	Order order = facets.startAndExecute(processId, operator, params);
        	wsResp.setOrderId(order.getId());
        } else {
            String methodStr = request.getParameter(Constant.PARA_METHOD);
            int method;
            try {
                method = Integer.parseInt(methodStr);
            } catch(Exception e) {
                method = 0;
            }
            switch(method) {
                case 0://任务执行
                    facets.execute(taskId, operator, params);
                    break;
                case -1://驳回、任意跳转
                    facets.executeAndJump(taskId, operator, params, request.getParameter(Constant.PARA_NODENAME));
                    break;
                case 1://转办
                    if(StringUtils.isNotEmpty(nextOperator)) {
                        facets.transferMajor(taskId, operator, nextOperator.split(","));
                    }
                    break;
                case 2://协办
                    if(StringUtils.isNotEmpty(nextOperator)) {
                        facets.transferAidant(taskId, operator, nextOperator.split(","));
                    }
                    break;
                default:
                    facets.execute(taskId, operator, params);
                    break;
            }
        }
        String ccOperator = request.getParameter(Constant.PARA_CCOPERATOR);
        if(StringUtils.isNotEmpty(ccOperator)) {
            facets.getEngine().order().createCCOrder(orderId, operator, ccOperator.split(","));
        }
        return wsResp;
    }

    /**
     * 通过流程名称启动流程
     * @return
     */
    @SuppressWarnings("rawtypes")
    @ResponseBody
	@RequestMapping(value = "startUp")
    public WsCommonResponse startUpByProcessName(HttpServletRequest request) {
    	WsCommonResponse wsResp = new WsCommonResponse();
    	
    	String processName = request.getParameter(Constant.PARA_PROCESSNAME);
    	String operator = request.getParameter(Constant.PARA_OPERATOR);
    	
        Order order = facets.startInstanceByName(processName, null, operator, null);
        wsResp.setOrderId(order.getId());
        wsResp.setMsg("启动流程成功.");
        
        return wsResp;
    }
    
    /**
     * 结束流程实例（包括所有活动任务）
     * @return
     */
    @SuppressWarnings("rawtypes")
	@ResponseBody
	@RequestMapping(value = "terminate")
    public WsCommonResponse terminate(HttpServletRequest request) {
    	WsCommonResponse wsResp = new WsCommonResponse();
    	
    	String orderId = request.getParameter(Constant.PARA_ORDERID);
    	String operator = request.getParameter(Constant.PARA_OPERATOR);
    	
    	facets.terminate(orderId, operator);
    	wsResp.setMsg("结束流程实例成功.");
        
        return wsResp;
    }
}
